#include "moz_profile.hpp"
#include <algorithm>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iterator>
#include <boost/algorithm/string.hpp>

const char moz_profile_dispatch::DELIMITER = ',';
const char moz_profile_dispatch::COMMENT = '#';

bool moz_profile_data::init_from(std::string& line, const char DELIMITER)
{
	if(std::count(line.begin(), line.end(), DELIMITER) != PROPERTIES-1)
	{
		std::cerr << "missing fields in profile structure" << std::endl;
		return false;
	}
	
	line_name = line.substr(0, line.find_first_of(DELIMITER));

	line = line.substr(line.find_first_of(DELIMITER)+1, line.length());
	moz_command_filename = line.substr(0, line.find_first_of(DELIMITER));
	boost::trim(moz_command_filename);

	moz_related_datafile = line.substr(line.find_first_of(DELIMITER)+1, line.length());
	boost::trim(moz_related_datafile);

	return true;
}


moz_profile_data::moz_profile_data(): 
	line_name(""),  moz_command_filename(""), moz_related_datafile("")
{}



std::string const moz_profile_data::get_name() const
{
	return line_name;
}

std::string const moz_profile_data::get_command_filename() const
{
	return moz_command_filename;
}

std::string const moz_profile_data::get_data_filename() const
{
	return moz_related_datafile;
}


moz_profile_data const moz_profile_data::operator=(moz_profile_data const& _data)
{
	line_name = _data.line_name;
	moz_command_filename = _data.moz_command_filename;
	moz_related_datafile = _data.moz_related_datafile;

	return *this;
}


std::ostream& operator << (std::ostream& ost, moz_profile_data const& c)
{
	ost << c.line_name << ", " << c.moz_command_filename << ", " << c.moz_related_datafile << std::endl;
	return ost;
}

moz_profile_dispatch::moz_profile_dispatch(const char* filename, int _profile_id)
{
	init_from(filename, _profile_id);
	std::cout << *this << std::endl;
}

moz_profile_dispatch::moz_profile_dispatch(std::string const& _filename, int _profile_id)
{
	init_from(_filename, _profile_id);
}


bool moz_profile_dispatch::init_from(const char *filename, int _profile_id)
{
	profile_id = _profile_id;
	return parse(filename, _profile_id);

}

bool moz_profile_dispatch::init_from(std::string const& _filename, int _profile_id)
{
	profile_id = _profile_id;
	return parse(_filename.c_str(), _profile_id);

}

bool moz_profile_dispatch::parse(const char *filename, int _profile_id)
{
	std::string line;
	std::ifstream input_file(filename);

	unsigned int num, pre_profile_id(0), profile_no = _profile_id;
	bool status(false);

	if (input_file.is_open())
	{
		while ( input_file.good() )
		{
			std::getline (input_file,line);
			line = boost::trim_left_copy(line);
			if(line[0] == COMMENT) continue;

			std::string directive = line.substr(0, line.find_first_of(DELIMITER));
			boost::trim(directive);

			std::stringstream id(directive);
			id >> num;

			if((status = (id.rdbuf()->in_avail() == 0))) // in case it is a number
			{
				if(profile_no == num) // as long as line is related to profile_no
				{
					line = line.substr(line.find_first_of(DELIMITER)+1, line.length());
					directive = line.substr(0, line.find_first_of(DELIMITER)); // extract preliminary profile_id
					boost::trim(directive);

					line = line.substr(line.find_first_of(DELIMITER)+1, line.length()); // extract current profile dispatching information
					moz_profile_data data;

					if(!(status = data.init_from(line, DELIMITER))) break;

					_profile_dispatch_list.push_front(data); 				
					
					std::stringstream prec_id(directive);
					prec_id >> pre_profile_id;

					status = ( prec_id.rdbuf()->in_avail() == 0 );  // as long as the preliminary profile id is a number

					if(status  // as long as the preliminary profile id is a number
						&& (pre_profile_id < profile_no))
					{
							profile_no = pre_profile_id;
							input_file.seekg(0, std::ios_base::beg);
					}
					else break;										
				}
			}
			else break;			
		}
	}

	input_file.close();

	return status;
}


bool moz_profile_dispatch::empty()
{
	return _profile_dispatch_list.empty();
}


/*
moz_profile_dispatch::moz_profile_dispatch(std::string const& _filename)
{
	profile_id = query_profile(_filename.c_str());
	parse(_filename.c_str(), profile_id);

}

moz_profile_dispatch::moz_profile_dispatch(const char* filename)
{
	profile_id = query_profile(filename);
	parse(filename, profile_id);
}

unsigned int moz_profile_dispatch::query_profile(const char* filename)
{
	return 0;
}
*/


template<class T> std::ostream& operator <<(std::ostream& os, const std::list<T>& v)
{
	std::copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout)); 
    return os;
}

std::ostream& operator << (std::ostream& ost, moz_profile_dispatch const& c)
{
	ost << c.profile_id << std::endl;
	ost << c._profile_dispatch_list;
	return ost;
}

#include "moz_dispatch.hpp"

void moz_profile_dispatch::dispatch(FILE** file, std::string const& _connection_str) const
{
	if(file != NULL)
	{
		for(std::list < moz_profile_data >::const_iterator _profile_iter = _profile_dispatch_list.begin(); 
			_profile_iter != _profile_dispatch_list.end(); _profile_iter++)
		{
			std::string command_filename(_profile_iter->get_command_filename());
			std::string value_filename(_profile_iter->get_data_filename());

			moz_dispatch  moz_command_list(command_filename, value_filename);
			if(!moz_command_list.dispatch(file, _connection_str)) break;

		}
	}
}
